﻿using System;
using System.Security.Principal;
using System.Threading.Tasks;
using Tiscs.Practices.Diagnostics;

namespace Tiscs.Practices.Web.Services.Client
{
    /// <summary>
    /// 身份验证服务客户端异步任务扩展。
    /// </summary>
    public static class AuthenticationServiceClientAsyncExtension
    {
        /// <summary>
        /// 异步获取当前用户。
        /// </summary>
        /// <typeparam name="T">用户信息类的类型。</typeparam>
        /// <param name="client">身份验证客户端实例。</param>
        /// <param name="userState">用户状态。</param>
        /// <returns>异步任务实例。</returns>
        public static Task<T> GetUserAsync<T>(this IAuthenticationServiceClient<T> client, object userState = null) where T : IPrincipal
        {
            Exception exception;
            if (!Validation.Parameter<IAuthenticationServiceClient<T>>(nameof(client)).AssertNotNull().CheckRules(client, out exception))
            {
                throw exception;
            }
            return Task.Factory.FromAsync<T>(client.BeginGetUser, client.EndGetUser, userState);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T">用户信息类的类型。</typeparam>
        /// <param name="client">身份验证客户端实例。</param>
        /// <param name="parameters">用户登录参数。</param>
        /// <param name="userState">用户状态。</param>
        /// <returns>异步任务实例。</returns>
        public static Task<T> SignInAsync<T>(this IAuthenticationServiceClient<T> client, SignInParameters parameters, object userState = null) where T : IPrincipal
        {
            Exception exception;
            if (!Validation.Parameter<IAuthenticationServiceClient<T>>(nameof(client)).AssertNotNull().CheckRules(client, out exception))
            {
                throw exception;
            }
            if (!Validation.Parameter<SignInParameters>(nameof(parameters)).AssertNotNull().CheckRules(parameters, out exception))
            {
                throw exception;
            }
            return SignInAsync<T>(client, parameters.UserName, parameters.Password, parameters.CustomData, parameters.IsPersistent, userState);
        }

        /// <summary>
        /// 用户异步登录。
        /// </summary>
        /// <typeparam name="T">用户信息类的类型。</typeparam>
        /// <param name="client">身份验证客户端实例。</param>
        /// <param name="userName">用户名。</param>
        /// <param name="password">密码。</param>
        /// <param name="customCredential">自定义凭据。</param>
        /// <param name="isPersistent">是否持久登录。</param>
        /// <param name="userState">用户状态。</param>
        /// <returns>异步任务实例。</returns>
        public static Task<T> SignInAsync<T>(this IAuthenticationServiceClient<T> client, string userName, string password, string customCredential, bool isPersistent, object userState = null) where T : IPrincipal
        {
            Exception exception;
            if (!Validation.Parameter<IAuthenticationServiceClient<T>>(nameof(client)).AssertNotNull().CheckRules(client, out exception))
            {
                throw exception;
            }
            return Task.Factory.FromAsync<T>((callback, userstate) => client.BeginSignIn(userName, password, customCredential, isPersistent, callback, userstate), client.EndSignIn, userState);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T">用户信息类的类型。</typeparam>
        /// <param name="client">身份验证客户端实例。</param>
        /// <param name="userState">用户状态。</param>
        /// <returns>异步任务实例。</returns>
        public static Task<T> SignOutAsync<T>(this IAuthenticationServiceClient<T> client, object userState = null) where T : IPrincipal
        {
            Exception exception;
            if (!Validation.Parameter<IAuthenticationServiceClient<T>>(nameof(client)).AssertNotNull().CheckRules(client, out exception))
            {
                throw exception;
            }
            return Task.Factory.FromAsync<T>(client.BeginSignOut, client.EndSignOut, userState);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T">用户信息类的类型。</typeparam>
        /// <param name="client">身份验证客户端实例。</param>
        /// <param name="user">用户信息实例。</param>
        /// <param name="userState">用户状态。</param>
        /// <returns>异步任务实例。</returns>
        public static Task UpdateUserAsync<T>(this IAuthenticationServiceClient<T> client, T user, object userState = null) where T : IPrincipal
        {
            Exception exception;
            if (!Validation.Parameter<IAuthenticationServiceClient<T>>(nameof(client)).AssertNotNull().CheckRules(client, out exception))
            {
                throw exception;
            }
            return Task.Factory.FromAsync<T>(client.BeginUpdateUser, client.EndUpdateUser, user, userState);
        }
    }
}
